package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.AddCartNumOverOutOfRestrictNumException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.mall.constant.ShoppingRetCode;
import com.cskaoyan.mall.dto.ClearCartItemRequest;
import com.cskaoyan.mall.dto.ClearCartItemResponse;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.entitys.Stock;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dal.persistence.StockMapper;
import com.cskaoyan.shopping.dto.*;
import com.cskaoyan.shopping.service.ICartService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @auther cskaoyan
 * @date 2022/6/16:16:34
 */
@Slf4j
@Service
public class ICartSeviceImpl implements ICartService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ItemMapper itemMapper;

    @Autowired
    StockMapper stockMapper;

    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {

        CartListByIdResponse response = new CartListByIdResponse();
        try {
            // 获取用户id
            request.requestCheck();
            Long userId = request.getUserId();
            // 从redis中获取数据
            RMap<String, CartProductDto> map = redissonClient.getMap(userId.toString());

            Collection<CartProductDto> values = map.values();
            List<CartProductDto> cartProductDtos = new ArrayList<>(values);

            // 将购物车返回
            response.setCartProductDtos(cartProductDtos);

            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartSeviceImpl.getCartsList occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request){

        AddCartResponse response = new AddCartResponse();

        try {
            request.requestCheck();
            Long userId = request.getUserId();

            RMap<String, CartProductDto> map = redissonClient.getMap(userId.toString());
            // 获得商品id
            Long productId = request.getItemId();

            // 根据商品id 取出对应的商品对象
            CartProductDto productDto = map.get(productId.toString());
            if(productDto == null){
                //redis中该用户没有该商品
                // 根据productId 查出商品的信息
                Item item = itemMapper.selectByPrimaryKey(productId);

                // 转化为CartProductDto
                productDto = CartItemConverter.item2Dto(item);
                // 设置购买数量
                productDto.setProductNum((long)request.getNum());
                // 首次加入购物车的勾选状态默认为true
                productDto.setChecked("true");
            }else {
                //redis中该用户有该商品
                // 增加该商品的数量
                productDto.setProductNum(productDto.getProductNum() + request.getNum());

            }
            // 添加到库存商品表中
            // addProductToStock(productDto);
            // 放入之前，检查购买数量是否符合要求
            checkRequestNum(productDto);

            // 放回redis中，相同key会覆盖
            map.put(productId.toString(),productDto);

            // 运行成功
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICartSeviceImpl.addProductToCart occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    /**
     * 加入购物车前，先添加到商品库存表
     * @param productDto
     */
    private void addProductToStock(CartProductDto productDto) {
        Stock stock = new Stock();
        stock.setItemId(productDto.getProductId());
        Stock stockInDataBase = stockMapper.selectByPrimaryKey(productDto.getProductId());
        if(stockInDataBase != null){
            //数据库不为空就不放了
            return;
        }
        // 商品库存默认为 1000件
        // 限购数量默认为
        int restrictCount = new Random().nextInt(100);
        long stockCount = new Random().nextInt(10000);
        if(restrictCount > stockCount){
            stockCount = restrictCount;
        }
        stock.setRestrictCount(restrictCount);
        stock.setStockCount(stockCount);
        stock.setLockCount(0);
        stockMapper.insertSelective(stock);
    }

    /**
     * 检查请求购买的数量是否大于限购数量和库存数量
     * 完成限购数量的赋值
     * @param productDto
     * @param productDto
     */
    private void checkRequestNum(CartProductDto productDto) {
        Long productId = productDto.getProductId();
        // 查出商品库存表中的限购数量,将购买数量与限购数量进行比对
        Stock stock = stockMapper.selectByPrimaryKey(productId);

        Long num = productDto.getProductNum();
        if(num > stock.getRestrictCount()){
            // 加入购物车数量大于限购数量
            throw new AddCartNumOverOutOfRestrictNumException(ShoppingRetCode.EXCEED_ITEM_RESTRICT_COUNT.getCode(), ShoppingRetCode.EXCEED_ITEM_RESTRICT_COUNT.getMessage());
        }

        if(num > stock.getStockCount()){
            // 加入购物车数量大于库存数量
            throw new AddCartNumOverOutOfRestrictNumException(ShoppingRetCode.EXCEED_ITEM_RESTRICT_COUNT.getCode(), ShoppingRetCode.EXCEED_ITEM_RESTRICT_COUNT.getMessage());
        }

        productDto.setLimitNum((long)stock.getRestrictCount());
    }

    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();
        try {
            request.requestCheck();
            Long userId = request.getUserId();
            RMap<String, CartProductDto> map = redissonClient.getMap(userId.toString());

            // 获得商品id
            Long productId = request.getItemId();
            CartProductDto productDto = map.get(productId.toString());
            productDto.setProductNum((long)request.getNum());
            //  购买数量符合要求
            checkRequestNum(productDto);

            //  更新勾选状态
            productDto.setChecked(request.getChecked());

            map.put(productId.toString(),productDto);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartSeviceImpl.updateShoppingCart occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request){
        CheckAllItemResponse checkAllItemResponse = new CheckAllItemResponse();
        try {
            request.requestCheck();
            String checked = request.getChecked();
            Long userId = request.getUserId();
            RMap<Object, CartProductDto> map = redissonClient.getMap(userId.toString());
            Set<Map.Entry<Object, CartProductDto>> entries = map.entrySet();
            Iterator<Map.Entry<Object, CartProductDto>> iterator = entries.iterator();
            while (iterator.hasNext()) {
                Map.Entry<Object, CartProductDto> next = iterator.next();
                next.getValue().setChecked(checked);
                map.put(next.getKey(), next.getValue());
            }
            checkAllItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            checkAllItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartServiceImpl.checkAllCartItem occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(checkAllItemResponse,e);
        }
        return checkAllItemResponse;
    }

    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request){
        DeleteCartItemResponse deleteCartItemResponse = new DeleteCartItemResponse();
        try {
            request.requestCheck();
            //获取到添加到购物车的商品的基本信息
            Long userId = request.getUserId();
            Long itemId = request.getItemId();
            //判断商品是否在购物车中已经存在
            RMap<Object, Object> map = redissonClient.getMap(userId.toString());
            //这里有可能因为取出的对象是null会导致强转出错
            CartProductDto cartProductItem = (CartProductDto) map.get(itemId.toString());
            //根据商品信息获取数据库中商品对象
            if (cartProductItem == null) {
                //如果用户购物车中的删除商品为空的话,说明参数有问题
                throw new ValidateException(SysRetCodeConstants.DATA_NOT_EXIST.getCode(), SysRetCodeConstants.DATA_NOT_EXIST.getMessage());
            }
            map.remove(itemId.toString());
            deleteCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (ValidateException e) {
            log.error("ICartServiceImpl.deleteCartItem occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(deleteCartItemResponse,e);
        }
        return deleteCartItemResponse;
    }

    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request){
        DeleteCheckedItemResposne deleteCheckedItemResposne = new DeleteCheckedItemResposne();
        try {
            request.requestCheck();
            Long userId = request.getUserId();
            RMap<Object, CartProductDto> map = redissonClient.getMap(userId.toString());
            Collection<CartProductDto> values = map.values();
            Iterator<CartProductDto> iterator = values.iterator();
            while (iterator.hasNext()) {
                if ("true".equals(iterator.next().getChecked())) {
                    iterator.remove();
                }
            }
            deleteCheckedItemResposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICartServiceImpl.deleteCheckedItem occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(deleteCheckedItemResposne,e);
        }
        return deleteCheckedItemResposne;
    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        ClearCartItemResponse response = new ClearCartItemResponse();
        try {
            request.requestCheck();
            Long userId = request.getUserId();
            List<Long> productIds = request.getProductIds();
            RMap<String, CartProductDto> map = redissonClient.getMap(userId.toString());

            for (Long productId : productIds) {
                map.remove(productId.toString());
            }

            // 运行成功
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        }catch (Exception e){
            log.error("ShoppingCartServiceImpl.getCartsList occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }
}
